/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFUnpacker
  \brief the abstract base class for unpacking of the raw data from Daq.
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-09-27
  \date 2021-09-27 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date        <th>Author      <th>Description                    </tr>
  <tr>  <td>2021-09-27   <td>Asia Sun    <td>file created                   </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef ETFUnpacker_h
#define ETFUnpacker_h

#include <string>
#include "DaqType.h"

using std::string;

class TTree;
class TObject;
class TClonesArray;
class ETFReadShm;
class ETFParaManager;

class ETFUnpacker{
public:
  /// \param type: marks the different unpackers: e.g. VME, PXI, etc.
  ETFUnpacker(DaqType type, int id = 0);
  virtual ~ETFUnpacker();

  virtual void Init() = 0;
  virtual void Reset() = 0;
  virtual int GetOneEvent(FILE *file) = 0; ///< get 1 event to memory from file
  virtual int GetOneEvent(int *fstream) = 0; ///< get 1 event to memory from stream
  virtual bool UnpackGood() const{ return true; } ///< true: good; false: bad
  /// write one event to dst - simulate daq to test online applications in ETFAna
  virtual void WriteOneEvent(){}
  virtual bool Unpack() = 0; ///< complete the unpack and filling of the unpacked data

  unsigned GetCurrentEventIndex() const{ return fCurrentEventIndex; }
  unsigned Index() const{ return fCurrentEventIndex; }
  virtual void PrintSummary() = 0; ///< print unpacking summary
  virtual void Print(); ///< Print the unpacked data of the current event
  int GetNofProcessedEvent() const{ return fEventCnt; }
  const char *filename() const{ return fFileName.data(); }
  DaqType daqType() const{ return fType; }
  bool pxi() const{ return fType == kPXI; }
  bool eof() const{ return feof; }
  int id() const{ return fId; }
  unsigned long SizeCnt() const{ return fSizeCnt; }
  double SizeCntInMB() const{ return fSizeCnt / 1048576.; } // / 1024*1024

  void SetDebug(bool opt = true){ fDebug = opt; }
  void SetReadShm(ETFReadShm *r);
  void SetFileName(const string &f){ fFileName = f; }
  virtual void Close(); ///< do some clean-ups

  // ClassDef(ETFUnpacker, 0); ///< virtual unpacker for ETF

protected:
  virtual void Register() = 0; ///< register the raw data to tree

  DaqType fType; //! ///< daq type
  int fId; //! ///< id of the unpacker - there may be multiple daqs of the same type
  unsigned fCurrentEventIndex; ///< index of the current event
  unsigned fEventCnt; //! ///< total number of events processed
  unsigned long fSizeCnt; //! ///< unpacked data size in byte
  bool fDebug; //! ///< if debug or not
  bool fError; //! ///< error flag, indicting abnormal conditions (ev too large, etc.)
  bool feof; //! ///< whether eof encountered

  bool fIsOnlineSim; //! ///< whether simulating daq online
  ETFReadShm *fReadShm; //! ///< for simulating daq online facilities
  string fFileName; //! ///< file name of the offline file - ommit it in online mode
  ETFParaManager *fpm;
};

#endif
